package messageprocessors.clients;

import java.util.HashMap;
import java.util.Map;
import java.util.Observer;

import org.apache.log4j.Logger;

import util.DSPropertyManager;

import messages.DSMessage;
import messages.DSMessageType;

public class AppserverClient extends BaseClient {
	
	private static Logger log = Logger.getLogger(AppserverClient.class);
	//read xmpp id and password from properties file
	private static String networkid = "appserver";
			//DSPropertyManager.getInstance().getStringValue("appclientserverid", "appserver");
	private static String networkpw = "appserver";
	//DSPropertyManager.getInstance().getStringValue("appclientserverpassword", "appserver");

	public String ausgabe="Anzeige:\n";
	public Artikel lastArt;
	


	

	public AppserverClient() {
		this(networkid, networkpw);
	}
	
	
	public AppserverClient(Observer ob) {
		this(networkid, networkpw, ob);
	}
	

		
	/**
	 * Standardkonstruktor der klasse Light
	 * 
	 * Folgende Default Werte sind festgelegt: tapOpen mit 0 --> Wasserhahn ist
	 * Standardmae�ig zu bathEmpty mit 1 --> Wanne ist im Standardmae�ig Leer
	 * temperature mit -1 --> Temperatur ist undefiniert curtainOpen mit 0 -->
	 * Vorhang ist Standardmae�ig geschlossen
	 */
	public AppserverClient(String id, String xmppPassword) {
		super(id, xmppPassword);
	}
	
	public AppserverClient(String id, String xmppPassword, Observer ob) {
		this(id, xmppPassword);
		this.addObserver(ob);
	}

	@Override
	public void processMessage(DSMessage message) throws Exception {
		this.setChanged();
		this.notifyAll();
		log.debug("AppserverClient received: " + message);

		if (message == null) {
			log.debug("Retrieved null message!");
			throw new Exception("The received message is null!");
		}

		// check for errors --> handle errors
		if (message.getError() != null) {
			this.setLastErrorRetrieved(message.getError());
			log.debug(this.getId() + ": An error occured: "  + message.getError());
		}

		// status request message
		if (message.getType() == DSMessageType.STATUSREQUEST) {
			processStatusRequestMessage(message);
		}
		// command message
		else if (message.getType() == DSMessageType.COMMAND) {
			processCommandMessage(message);
		}
		//code request message
		else if (message.getType() == DSMessageType.CODEREQUEST) {
			processCodeMessage(message);
		}
		else if (message.getType() == DSMessageType.ERRORREQUEST) {
			processErrorMessage(message);
		}
		this.setChanged();
		this.notifyAll();
	}

	private void processCodeMessage(DSMessage msg)throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		Rohmaterial neuArt=new Rohmaterial();
		int codenr=msg.getIntValueForKey("barcode");
		neuArt=(Rohmaterial) sucheArtikel(codenr);
		neuArt.createMap();
		this.lastArt=neuArt;
		map=neuArt.getMap();
		DSMessage msg2=new DSMessage(map);
		msg2.setTargetId(msg.getOriginId());
		msg2.setType(DSMessageType.CODEREQUEST);
		msg2.setOriginId("appserver");
		this.ausgabe+="Coderequest"+map.toString();
		sendMessage(msg2,msg.getOriginId());
		sendMessageToJavaServer(msg2);
		this.setChanged();
		this.notifyAll();
	}
	
	private void processErrorMessage(DSMessage msg)throws Exception{
		
		Map<String, String> map = new HashMap<String, String>();
		Artikel neuArt=new Artikel();
		int barcodenum=msg.getIntValueForKey("barcode");
		String status=msg.getStringValueForKey("status");
		String info=msg.getStringValueForKey("Info");
		neuArt=sucheArtikel(barcodenum);
		neuArt.setStatus(status);
		neuArt.setInfo(info);
		this.lastArt=neuArt;
		writeindb(neuArt);
		this.ausgabe+="Coderequest"+map.toString();
		this.setChanged();
		this.notifyAll();
	}
	
	private Artikel sucheArtikel(int codenr){
		//TODO
		return null;
	}
	private void processCommandMessage(DSMessage msg) throws Exception {
		Artikel neuArt=new Artikel();
		
		try {
			neuArt.generateArtikel(msg.getPropertyMap());
			this.ausgabe+="Command"+neuArt.getMap().toString();
			setAusgabe(ausgabe);
			sucheArtikel(neuArt.getBarcode());
			writeindb(neuArt);
			this.lastArt=neuArt;
			this.setChanged();
			this.notifyAll();
			log.debug("Reading new values from message!");
		} catch (Exception e) {
		}
	}
	
	private void writeindb(Artikel neuArt){
		//TODO
	}

	private void processStatusRequestMessage(DSMessage msg) throws Exception {
		//check where to send the status
		String originid = msg.getOriginId();
		if(originid==null) {
			log.error("No origin id was specified in the status message!");
			throw new Exception("Couldn't get origin id for status message!");
		}
		
		//Send status to server, set the target id to the origin id of the received message
		reportStatus(originid);
	}

	@Override
	protected Map<String, String> generatePropertyMap() {
		
		//put everything into our map
		Map<String, String> map = new HashMap<String, String>();
		
		return map;
	}

	/**
	 * @return the ausgabe
	 */
	public String getAusgabe() {
		return ausgabe;
	}

	/**
	 * @param ausgabe the ausgabe to set
	 */
	public void setAusgabe(String ausgabe) {
		this.ausgabe += ausgabe;
	}


	/**
	 * @return the lastArt
	 */
	public Artikel getLastArt() {
		return lastArt;
	}


	/**
	 * @param lastArt the lastArt to set
	 */
	public void setLastArt(Artikel lastArt) {
		this.lastArt = lastArt;
	}
	

}
